home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / sendmail / sendmail-5.65 / src / macro.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-06-05  |  5.4 KB  |  246 lines

  1. /*
  2.  * Copyright (c) 1983 Eric P. Allman
  3.  * Copyright (c) 1988 Regents of the University of California.
  4.  * All rights reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms are permitted provided
  7.  * that: (1) source distributions retain this entire copyright notice and
  8.  * comment, and (2) distributions including binaries display the following
  9.  * acknowledgement:  ``This product includes software developed by the
  10.  * University of California, Berkeley and its contributors'' in the
  11.  * documentation or other materials provided with the distribution and in
  12.  * all advertising materials mentioning features or use of this software.
  13.  * Neither the name of the University nor the names of its contributors may
  14.  * be used to endorse or promote products derived from this software without
  15.  * specific prior written permission.
  16.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  17.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  18.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  19.  */
  20.  
  21. #ifndef lint
  22. static char sccsid[] = "@(#)macro.c    5.7 (Berkeley) 6/1/90";
  23. #endif /* not lint */
  24.  
  25. # include "sendmail.h"
  26.  
  27. /*
  28. **  EXPAND -- macro expand a string using $x escapes.
  29. **
  30. **    Parameters:
  31. **        s -- the string to expand.
  32. **        buf -- the place to put the expansion.
  33. **        buflim -- the buffer limit, i.e., the address
  34. **            of the last usable position in buf.
  35. **        e -- envelope in which to work.
  36. **
  37. **    Returns:
  38. **        none.
  39. **
  40. **    Side Effects:
  41. **        none.
  42. */
  43.  
  44. expand(s, buf, buflim, e)
  45.     register char *s;
  46.     register char *buf;
  47.     char *buflim;
  48.     register ENVELOPE *e;
  49. {
  50.     register char *xp;
  51.     register char *q;
  52.     bool skipping;        /* set if conditionally skipping output */
  53.     bool recurse = FALSE;    /* set if recursion required */
  54.     int i;
  55.     char xbuf[BUFSIZ];
  56.     extern char *macvalue();
  57.  
  58.     if (tTd(35, 24))
  59.     {
  60.         printf("expand(");
  61.         xputs(s);
  62.         printf(")\n");
  63.     }
  64.  
  65.     skipping = FALSE;
  66.     if (s == NULL)
  67.         s = "";
  68.     for (xp = xbuf; *s != '\0'; s++)
  69.     {
  70.         char c;
  71.  
  72.         /*
  73.         **  Check for non-ordinary (special?) character.
  74.         **    'q' will be the interpolated quantity.
  75.         */
  76.  
  77.         q = NULL;
  78.         c = *s;
  79.         switch (c)
  80.         {
  81.           case CONDIF:        /* see if var set */
  82.             c = *++s;
  83.             skipping = macvalue(c, e) == NULL;
  84.             continue;
  85.  
  86.           case CONDELSE:    /* change state of skipping */
  87.             skipping = !skipping;
  88.             continue;
  89.  
  90.           case CONDFI:        /* stop skipping */
  91.             skipping = FALSE;
  92.             continue;
  93.  
  94.           case '\001':        /* macro interpolation */
  95.             c = *++s;
  96.             q = macvalue(c & 0177, e);
  97.             if (q == NULL)
  98.                 continue;
  99.             break;
  100.         }
  101.  
  102.         /*
  103.         **  Interpolate q or output one character
  104.         */
  105.  
  106.         if (skipping || xp >= &xbuf[sizeof xbuf])
  107.             continue;
  108.         if (q == NULL)
  109.             *xp++ = c;
  110.         else
  111.         {
  112.             /* copy to end of q or max space remaining in buf */
  113.             while ((c = *q++) != '\0' && xp < &xbuf[sizeof xbuf - 1])
  114.             {
  115.                 if (iscntrl(c) && !isspace(c))
  116.                     recurse = TRUE;
  117.                 *xp++ = c;
  118.             }
  119.         }
  120.     }
  121.     *xp = '\0';
  122.  
  123.     if (tTd(35, 24))
  124.     {
  125.         printf("expand ==> ");
  126.         xputs(xbuf);
  127.         printf("\n");
  128.     }
  129.  
  130.     /* recurse as appropriate */
  131.     if (recurse)
  132.     {
  133.         expand(xbuf, buf, buflim, e);
  134.         return;
  135.     }
  136.  
  137.     /* copy results out */
  138.     i = buflim - buf - 1;
  139.     if (i > xp - xbuf)
  140.         i = xp - xbuf;
  141.     bcopy(xbuf, buf, i);
  142.     buf[i] = '\0';
  143. }
  144. /*
  145. **  DEFINE -- define a macro.
  146. **
  147. **    this would be better done using a #define macro.
  148. **
  149. **    Parameters:
  150. **        n -- the macro name.
  151. **        v -- the macro value.
  152. **        e -- the envelope to store the definition in.
  153. **
  154. **    Returns:
  155. **        none.
  156. **
  157. **    Side Effects:
  158. **        e->e_macro[n] is defined.
  159. **
  160. **    Notes:
  161. **        There is one macro for each ASCII character,
  162. **        although they are not all used.  The currently
  163. **        defined macros are:
  164. **
  165. **        $a   date in ARPANET format (preferring the Date: line
  166. **             of the message)
  167. **        $b   the current date (as opposed to the date as found
  168. **             the message) in ARPANET format
  169. **        $c   hop count
  170. **        $d   (current) date in UNIX (ctime) format
  171. **        $e   the SMTP entry message+
  172. **        $f   raw from address
  173. **        $g   translated from address
  174. **        $h   to host
  175. **        $i   queue id
  176. **        $j   official SMTP hostname, used in messages+
  177. **        $l   UNIX-style from line+
  178. **        $n   name of sendmail ("MAILER-DAEMON" on local
  179. **             net typically)+
  180. **        $o   delimiters ("operators") for address tokens+
  181. **        $p   my process id in decimal
  182. **        $q   the string that becomes an address -- this is
  183. **             normally used to combine $g & $x.
  184. **        $r   protocol used to talk to sender
  185. **        $s   sender's host name
  186. **        $t   the current time in seconds since 1/1/1970
  187. **        $u   to user
  188. **        $v   version number of sendmail
  189. **        $w   our host name (if it can be determined)
  190. **        $x   signature (full name) of from person
  191. **        $y   the tty id of our terminal
  192. **        $z   home directory of to person
  193. **
  194. **        Macros marked with + must be defined in the
  195. **        configuration file and are used internally, but
  196. **        are not set.
  197. **
  198. **        There are also some macros that can be used
  199. **        arbitrarily to make the configuration file
  200. **        cleaner.  In general all upper-case letters
  201. **        are available.
  202. */
  203.  
  204. define(n, v, e)
  205.     char n;
  206.     char *v;
  207.     register ENVELOPE *e;
  208. {
  209.     if (tTd(35, 9))
  210.     {
  211.         printf("define(%c as ", n);
  212.         xputs(v);
  213.         printf(")\n");
  214.     }
  215.     e->e_macro[n & 0177] = v;
  216. }
  217. /*
  218. **  MACVALUE -- return uninterpreted value of a macro.
  219. **
  220. **    Parameters:
  221. **        n -- the name of the macro.
  222. **
  223. **    Returns:
  224. **        The value of n.
  225. **
  226. **    Side Effects:
  227. **        none.
  228. */
  229.  
  230. char *
  231. macvalue(n, e)
  232.     char n;
  233.     register ENVELOPE *e;
  234. {
  235.     n &= 0177;
  236.     while (e != NULL)
  237.     {
  238.         register char *p = e->e_macro[n];
  239.  
  240.         if (p != NULL)
  241.             return (p);
  242.         e = e->e_parent;
  243.     }
  244.     return (NULL);
  245. }
  246.